package hotel.controller.user;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;

import java.io.IOException;
import java.util.List;

import hotel.common.MsgBox;
import hotel.dao.HotelDao;
import hotel.modal.User;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TableView.TableViewSelectionModel;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.converter.IntegerStringConverter;

public class UserManageController {
	@FXML private TableView<User> tableView;
	@FXML private TableColumn<User, String> userNameCol;
	@FXML private TableColumn<User, Integer> employeeIdCol;
	@FXML private TableColumn<User, Boolean> adminCol;
	@FXML private Button btnAdd;
	@FXML private Button btnDel;
	
	@FXML
    public void initialize() {
		// 设置模型Integer属性和表格String属性之间的转换
		employeeIdCol.setCellFactory(TextFieldTableCell.<User, Integer>forTableColumn(new IntegerStringConverter()));
		
		employeeIdCol.setCellFactory(new Callback<TableColumn<User, Integer>, TableCell<User, Integer>>() {
			@Override
			public TableCell<User, Integer> call(TableColumn<User, Integer> col) {
				return new TableCell<User, Integer>() {
					@Override
					protected void updateItem(Integer item, boolean empty) {
						super.updateItem(item, empty);
						if(empty) {
							setText(null);
						}else {
							if(item.intValue() == -1) setText("未绑定");
							else setText(Integer.toString(item));
						}
					}
				};
			}	
		});
		
		// 设置模型Boolean属性和表格String属性之间的转换
		adminCol.setCellFactory(col -> new TableCell<User, Boolean>() {
			@Override
			protected void updateItem(Boolean item, boolean empty) {
		        super.updateItem(item, empty) ;
		        if(empty == true) setText(null);
		        else if(item == true) setText("是");
		        else setText("否");
		    }
		});
		
		// 设置表格行右键菜单
		tableView.setRowFactory(
			    new Callback<TableView<User>, TableRow<User>>() {
			  @Override
			  public TableRow<User> call(TableView<User> tableView) {
			    final TableRow<User> row = new TableRow<>();
			    
			    final ContextMenu rowMenu = new ContextMenu();
			    MenuItem changeItem = new MenuItem("更改");
			    
			    changeItem.setOnAction(new EventHandler<ActionEvent>() {
			    	@Override
			    	public void handle(ActionEvent event) {
			    		User user = row.getItem();
			    		changeUser(user);
			    	}
			    });
			  
			    MenuItem removeItem = new MenuItem("删除");
			    
			    removeItem.setOnAction(new EventHandler<ActionEvent>() {
			      @Override
			      public void handle(ActionEvent event) {
			    	User user = row.getItem();
			    	if(HotelDao.delete(user)) {
			    		tableView.getItems().remove(user);
			    		tableView.refresh();
			    	} else {
			    		MsgBox.showErrorDialog("错误", null, "删除失败！");
			    	}
			      }
			    });
			    
			    rowMenu.getItems().addAll(changeItem, removeItem);
			    
			    row.setOnMouseClicked(event -> {
			        if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
			            User user = row.getItem();
			            changeUser(user);
			        }
			    });

			    // only display context menu for non-null items:
			    row.contextMenuProperty().bind(
			      Bindings.when(Bindings.isNotNull(row.itemProperty()))
			      .then(rowMenu)
			      .otherwise((ContextMenu)null));
			    return row;
			  }
			});
		
		// 刷新整个table
		tableView.refresh();
				
		// 加载数据
		loadUserInfo(); 
	}
	
	public void loadUserInfo() {
		ObservableList<User> data = tableView.getItems();
		List<User> list = HotelDao.getAllUser();
		data.addAll(list);
	}
	
	private void changeUser(User user) {
		FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/user/UserDetails.fxml"));
		try {
			User tUser = new User(user);
			VBox vbox = (VBox)fxmlLoader.load();
			UserDetailsController controller = fxmlLoader.<UserDetailsController>getController();
			controller.initUser(tUser); // 向子窗口传递数据
			Stage stage = new Stage();
			stage.setScene(new Scene(vbox));
			stage.setTitle("更改用户信息");
			stage.setResizable(false);
			stage.initModality(Modality.APPLICATION_MODAL);
			stage.showAndWait(); // 显示窗口并等待用户操作
			ObservableList<User> data = tableView.getItems();
			if(tUser.isModified() && HotelDao.delete(user)) { // 判断是否被修改，然后移除以前的用户，并添加新的
				if(HotelDao.add(tUser)) { // 如果保存到数据库成功
					//System.out.println(user.toString());
					tUser.setModified(false);
					int index = tableView.getSelectionModel().getSelectedIndex();
					data.remove(user);
					data.add(index, tUser);
					tableView.getSelectionModel().select(index);
				}else {
					MsgBox.showErrorDialog("错误", "用户信息修改失败！", "可能输入不规范！");
				}
				
			}
			tableView.refresh(); // 刷新表格
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// Event Listener on Button[#btnAdd].onAction
	@FXML
	public void onBtnAddUser(ActionEvent event) {
		User user = new User();
		FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/user/UserAdd.fxml"));
		try {
			
			BorderPane pane = (BorderPane)fxmlLoader.load();
			UserAddController controller = fxmlLoader.<UserAddController>getController();
			controller.setInitData(user); // 向子窗口传递数据
			Stage stage = new Stage();
			stage.setScene(new Scene(pane));
			stage.setTitle("新增用户");
			stage.setResizable(false);
			stage.initModality(Modality.APPLICATION_MODAL);
			stage.showAndWait(); // 显示窗口并等待用户操作
			ObservableList<User> data = tableView.getItems();
			if(user.isModified()) {
				if(HotelDao.add(user)) { // 如果保存到数据库成功
					//System.out.println(user.toString());
					user.setModified(false);
					data.add(user);
					MsgBox.showInformationDialog("添加成功", null, "新用户("+ user.getUserName()+")已经添加成功！");
				}else {
					MsgBox.showErrorDialog("新增错误", "用户信息保存错误！", "可能用户名已经存在！");
				}
				
			}
			// 刷新表格
			tableView.refresh(); 
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	// Event Listener on Button[#btnDel].onAction
	@FXML
	public void onBtnDelUser(ActionEvent event) {
		TableViewSelectionModel<User> selectModel = tableView.getSelectionModel();
		int index = selectModel.getSelectedIndex();
		User user = selectModel.getSelectedItem();
		ObservableList<User> data = tableView.getItems();
    	if(HotelDao.delete(user)) {
    		data.remove(user);
    		if(data.size() > index) selectModel.select(index);
    		else if(data.size() > 0) selectModel.select(index - 1); 
    		tableView.refresh();
    	} else {
    		MsgBox.showErrorDialog("错误", null, "删除失败！");
    	}
	}
}
